﻿#include "ssReadFile.h"


namespace StarSeeker
{
#ifdef SS_USE_ANDROID
AAssetManager* ssReadFile::s_pAssetMgr = 0;
void ssReadFile::SetAndroidAssetManager(AAssetManager* asg)
{
	s_pAssetMgr = asg;
}
#endif

ssReadFile::ssReadFile()
{
	m_path = "";
#ifdef SS_USE_ANDROID
	m_asset = 0;
#endif
}

ssReadFile::~ssReadFile()
{
	Clear();
}

bool ssReadFile::SetBuffer( char *buf, ulint len )
{
	return m_buffer.Init(buf, len);
}

void ssReadFile::Clear()
{
	CloseFile();
	m_buffer.Empty();
}

bool ssReadFile::OpenFile( bool binary )
{
#ifdef SS_USE_ANDROID
	if (m_path.size()>7 && m_path[0]=='a' && m_path[1]=='s' && m_path[2]=='s' &&
		m_path[3]=='e' && m_path[4]=='t' && m_path[5]=='s')
	{
		m_asset = AAssetManager_open(ssReadFile::s_pAssetMgr, m_path.c_str()+7, AASSET_MODE_UNKNOWN);
		return m_asset!=0;
	}
#endif
	if (m_fstream.is_open())
		m_fstream.close();

	if (binary)
		m_fstream.open(m_path.c_str(), std::ios::binary);
	else
		m_fstream.open(m_path.c_str());

	return m_fstream.is_open();
}

void ssReadFile::CloseFile()
{
#ifdef SS_USE_ANDROID
	if(m_asset)
	{
		AAsset_close(m_asset);
		m_asset = 0;
	}
#endif
	m_fstream.close();
}

ulint ssReadFile::FileSize()
{
#ifdef SS_USE_ANDROID
	if (m_asset)
	{
		return AAsset_getLength(m_asset);
	}
#endif
	if (!m_fstream.is_open())
		return 0;

	m_fstream.seekg( 0, std::ios::end );
	ulint sz = (ulint)m_fstream.tellg();
	m_fstream.seekg( 0, std::ios::beg );
	return sz;
}

bool ssReadFile::GetLine( char *buf, ulint len )
{
#ifdef SS_USE_ANDROID
	if (m_asset)
	{
		if (m_readBytes.IsEmpty())
		{
			m_readBytes.Set((const char*)AAsset_getBuffer(m_asset), FileSize());
		}
		if (buf)
		{
			return m_readBytes.GetLine(buf, len)!=0;
		}
		else if (m_buffer.Buf())
		{
			return m_readBytes.GetLine(m_buffer.Buf(), m_buffer.MaxSize()).good();
		}
		else if (!m_buffer.Buf() && CreateBuffer())
		{
			return m_readBytes.GetLine(m_buffer.Buf(), m_buffer.MaxSize()).good();
		}
		return false;
	}
#endif
	if (!m_fstream.is_open())
		return false;
	if (buf)
	{
		return m_fstream.getline(buf, len).good();
	}
	else if (m_buffer.Buf())
	{
		return m_fstream.getline(m_buffer.Buf(), m_buffer.MaxSize()).good();
	}
	else if (!m_buffer.Buf() && CreateBuffer())
	{
		return m_fstream.getline(m_buffer.Buf(), m_buffer.MaxSize()).good();
	}
	return false;
}

bool ssReadFile::ReadAll()
{
	ulint sz = FileSize();
#ifdef SS_USE_ANDROID
	if (m_asset)
	{
		//int numBytesRead = AAsset_read(m_asset, m_buffer.Buf(), sz);
		char* buf = (char*)AAsset_getBuffer(m_asset);
		if (buf==0)
		{
			return false;
		}
		m_buffer.Init(buf, sz);
		m_buffer.SetSize(sz);
		return true;
	}
#endif
	if (!m_buffer.Buf())
	{
		CreateBuffer();
	}
	if (!m_buffer.Buf())
	{
		return false;
	}
	if (sz > m_buffer.MaxSize())
	{
		return false;
	}
	if (!m_fstream.is_open())
	{
		return false;
	}
	m_fstream.read(m_buffer.Buf(), sz);
	m_buffer.SetSize(sz);
	return true;
}

bool ssReadFile::CreateBuffer()
{
	if (!m_buffer.Buf())
	{
		ulint sz = FileSize();
		if (sz>0)
		{
			if (m_buffer.Init(sz+4))
			{
				m_buffer.Empty(true);
				return true;
			}
		}
	}
	return false;
}

}
